﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Testing
{
    public interface IClock
    {
        DateTime GetTime();
    }

    public class SystemClock : IClock
    {
        public DateTime GetTime()
        {
            return DateTime.Now;
        }
    }

    public class TestClock : IClock
    {
        public DateTime CurrentTime { get; set; }

        public DateTime GetTime()
        {
            return CurrentTime;
        }
    }

    class Person
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    public class Alarm
    {
        private readonly IClock _clock;
        readonly int _buzzLength = 1;

        DateTime AlarmTime { get; set; }

        public Alarm(DateTime alarmTime, IClock clock = null) // default args
        {
            _clock = clock ?? new SystemClock();
            AlarmTime = alarmTime;
        }

        public bool IsBuzzing()
        {
            var secondsAfterAlarmTime = ( _clock.GetTime() - AlarmTime).TotalSeconds;
            return secondsAfterAlarmTime >= 0 && secondsAfterAlarmTime < _buzzLength;
        }


        public bool IsSnoozed()
        {
            var secondsAfterAlarmTime = (_clock.GetTime() - AlarmTime).TotalSeconds;
            return secondsAfterAlarmTime >= 0 && secondsAfterAlarmTime < _buzzLength;
        }

    }
    // Declare the delegate handler for the event. The delegate
    // defines a signature that returns void and has no parameters.
    public delegate void MyEventHandler();

    class TestEvent
    {
        // Declare the event of type MyEventHandler. Event handlers
        // for TriggerIt must have the same signature as MyEventHandler.
        public event MyEventHandler TriggerIt;

        // Declare a method that triggers the event:
        public void Trigger()
        {
            TriggerIt();
        }
        // Declare the methods that will be associated with the TriggerIt event.
        public void MyMethod1()
        {
            System.Console.WriteLine("Hello!");
        }
        public void MyMethod2()
        {
            System.Console.WriteLine("Hello again!");
        }
        public void MyMethod3()
        {
            System.Console.WriteLine("Goodbye!");
        }

        public delegate int Task(); // delegate type
        public static int task1()
        {
            throw new Exception();
            return 0;
        }
        public static int task2()
        {
            return 0;
        }

        public event Task myEvent;

        static void Main()
        {
            var testEvent = new TestEvent();
            testEvent.myEvent += task1;
            testEvent.myEvent += task2;

            testEvent.myEvent();
            Task t;
            t = task1;
            t();

            t = delegate { return 4; };
            t = () => 2; // Lambda expression

            //var tasks = new List<Task> {task1, task2};

            //foreach (var task in tasks)
            //{
            //    try
            //    {
            //        log("started " + task.Method.Name);

            //        int x = task();
            //        log(x + " started surveys");
            //        log("stopped " + +task.Method.Name);
            //    }
            //    catch (Exception e)
            //    {
            //        log(e);
            //    }
            //}


























            // Create an instance of the TestEvent class.
            TestEvent myEvent = new TestEvent();

            // Subscribe to the event by associating the handlers with the event:
            myEvent.TriggerIt += myEvent.MyMethod1;
            myEvent.TriggerIt += new MyEventHandler(myEvent.MyMethod2);
            myEvent.TriggerIt += new MyEventHandler(myEvent.MyMethod2);
            myEvent.TriggerIt += new MyEventHandler(myEvent.MyMethod3);

            myEvent.TriggerIt = myEvent.MyMethod3;

            // Trigger the event:
            myEvent.Trigger();

            // Unsuscribe from the event by removing the handler from the event:
            myEvent.TriggerIt -= myEvent.MyMethod2;
            System.Console.WriteLine("\"Hello again!\" unsubscribed from the event.");

            // Trigger the new event:
            myEvent.Trigger();
            Console.ReadKey();
        }
    }
    //class Program
    //{
    //    static double foo(int a, int b)
    //    {
    //        return Math.Pow(a, b);
    //    }
    //    private delegate double DoubleIntInt(int a, int b); // delegate type
    //    static void Main(string[] args)
    //    {
    //        DoubleIntInt func;  // delegate reference

    //        func = foo; // assign to refernce a method

    //        func(1,2);  // invoke func

    //        var f = new Fraction.Fraction();
    //    }
    //}

}
